package cn.exrick.xboot.common.jiuqiCommon.callAPIUtil.dao;



import java.sql.*;
import java.util.*;

/**
 * JDBC 绝对封装jar包源码
 * @author CYL 2018-02-01
 *
 */
public class JDBCimpl {
	
	/**
	 * 创建所有的需要使用的接口或对象存储的属性
	 */
	private Connection connection = null;
	private Statement statement = null;
	private PreparedStatement preparedStatement = null;
	private ResultSet resultSet = null;
	private static Properties properties = null;
	private static String DRIVER;
	private static String URL;
	private static String USER;
	private static String PASSWORD;
	private static boolean COMMIT;
	
	
	//为了能够让静态初始化代码块中的驱动加载成功，需要让配置文件对象能够直接使用在static标识的代码块中
	/**
	 * 静态初始化代码块，初始化配置文件信息和加载驱动
	 */
	static{
/*		//1，读取配置文件的信息
		InputStream resourceAsStream = JDBCImpl.class.getClassLoader().getResourceAsStream("jdbc.properties");
		properties = new Properties();
		try {
			properties.load(resourceAsStream);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//2，将配置文件中的信息对上面的属性赋值
		DRIVER = properties.getProperty("driver");
		URL = properties.getProperty("url");
		USER = properties.getProperty("user");
		PASSWORD = properties.getProperty("password");
		COMMIT = Boolean.getBoolean(properties.getProperty("commit"));
		*/
			
		ResourceBundle rb = ResourceBundle.getBundle("jdbc");
		
		DRIVER = rb.getString("driver");
		URL = rb.getString("url");
		USER = rb.getString("user");
		PASSWORD = rb.getString("password");
		COMMIT = Boolean.valueOf(rb.getString("commit"));
		
		
		
		//3，加载驱动
		try {
			Class.forName(DRIVER);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 通过驱动管理类，来创建相应的数据库连接，并实现自动化事物处理的设定
	 */
	private void getConnection(){
		try {
			connection = DriverManager.getConnection(URL, USER, PASSWORD);
			connection.setAutoCommit(COMMIT);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	/***************************** 状态通道  ***********************************/
	
	
	/**
	 * 通过数据库连接，创建数据库操作的状态通道
	 * 需要先执行获取连接的方法
	 */
	private void getStatement(){
		getConnection();
		try {
			statement = connection.createStatement();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 状态通道的查询方法
	 * 需要先获取通道
	 * @param sql  即将要查询的SQL语句
	 * @return 查询的结果集
	 */
	public ResultSet select(String sql){
		getStatement();
		try {
			resultSet = statement.executeQuery(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return resultSet;
	}
	
	/**
	 * 状态通道的DML数据操作方法
	 * 需要先获取通道
	 * @param sql 数据库中DML数据操作语言
	 * @return 判断操作是否成功，成功true，失败false
	 * @throws SQLException
	 */
	public boolean update(String sql) throws SQLException{
		getStatement();
		boolean isok = false;
		int executeUpdate = statement.executeUpdate(sql);
		if(executeUpdate>0){
			isok = true;
		}
		return isok;
	}
	
	/**
	 * 状态的通道批量处理方法
	 * @param list 字符串类型的集合中存放的都是批量操作的SQL语句
	 * @return 判断操作是否成功，成功true，失败false
	 * @throws SQLException
	 */
	public boolean updates(List<String> list) throws SQLException{
		getStatement();
		boolean isok = true;
		for (int i = 0; i < list.size(); i++) {
			statement.addBatch(list.get(i));
		}
		
		int[] executeBatch = statement.executeBatch();
		
		for (int i = 0; i < executeBatch.length; i++) {
			if(executeBatch[i]<=0){
				isok = false;
			}
		}
		return isok;
	}
	
	
	/******************************  预通道  **********************************/
	
	/**
	 * 通过数据库连接创建预通道
	 * @param sql 需要添加预定义的SQL语句
	 */
	private void getPreparedStatement(String sql){
		getConnection();
		try {
			preparedStatement = connection.prepareStatement(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 对预定义的SQL语句中问号，自动化添加动态数据
	 * @param list 存储问号数据，按照问号从左到右的顺序排列
	 */
	private void setData(List<Object> list){
		for (int i = 0; i < list.size(); i++) {
			try {
				preparedStatement.setObject(i+1, list.get(i));
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 使用预通道做查询
	 * 需要先创建预通道，还需要传入相应的预定义数据
	 * @param sql 携带？号预定于查询语言
	 * @param list 携带问号参数需要的数据容器
	 * @return 查询的结果集
	 */
	public ResultSet select(String sql,List list){
		getPreparedStatement(sql);
		setData(list);
		
		try {
			resultSet = preparedStatement.executeQuery();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return resultSet;
	}
	
	/**
	 * 使用预通道做数据操作
	 * @param sql 携带？号的预处理SQL语句
	 * @param list 携带问号参数数据的集合容器
	 * @return  判断操作是否成功，成功true，失败false
	 * @throws SQLException
	 */
	public boolean update(String sql,List list) throws SQLException{
		getPreparedStatement(sql);
		setData(list);
		boolean isok = false;
		int executeUpdate = preparedStatement.executeUpdate();
		if(executeUpdate>0){
			isok = true;
		}
		return isok;
	}
	
	/*****************************  事物处理   *******************************/
	//因为事物处理的提交和回滚是需要使用连接对象的，我们不可以让连接对象随意的使用，所以也同样需要将事物处理设置成方法

	/**
	 * 设置事物提交
	 */
	public void commit(){
		try {
			connection.commit();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 设置事物回滚
	 */
	public void rollBack(){
		try {
			connection.rollback();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	/************************ 关闭所有的资源 *****************************/
	
	/**
	 * 自动化关闭所有的资源
	 */
	public void close(){
		
		try {
			if(resultSet != null){
				resultSet.close();
			}
			
			if(preparedStatement != null){
				preparedStatement.close();
			}
			
			if(statement != null){
				statement.close();
			}
			
			if(connection != null){
				connection.close();
			}
			
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	
	
	

}
